package org.jod.anarchytrek.component;

import org.jod.anarchytrek.AComponent;
import org.jod.anarchytrek.AInfo;
import org.jod.anarchytrek.IConsumerableComponent;
import org.jod.anarchytrek.ITurnableComponent;
import org.jod.anarchytrek.componentfactory.NacelleClass;
import org.jod.anarchytrek.info.NacelleInfo;
import org.jod.anarchytrek.util.MathUtil;

public class Nacelle extends AComponent implements IConsumerableComponent {

    private double _sustainableWarp;

    private double _fullWarp;

    private NacelleInfo _nacelleInfo;

    private double _orderedWarp;

    private double _effectiveWarp;

    private int _needEnergy;

    public Nacelle(NacelleInfo aNacelleInfo, NacelleClass aNacelleClass) {
        super(aNacelleClass.structuralUnits(), aNacelleInfo);
        _sustainableWarp = aNacelleClass.sustainableWarp();
        _fullWarp = aNacelleClass.fullWarp();
        _nacelleInfo = aNacelleInfo;
        _orderedWarp = 0;
        _effectiveWarp = 0;
        _needEnergy = 0;
        toInfo();
    }

    public void warp(double aOrderedWarp) {
        _orderedWarp = aOrderedWarp;
        _needEnergy = calcolateEnergyNeed(_orderedWarp);
        toInfo();
    }

    public int consume(int aEnergyAmout) {
        int returnedEnergy = 0;
        if (aEnergyAmout >= _needEnergy) {
            _effectiveWarp = _orderedWarp;
            returnedEnergy = aEnergyAmout - _needEnergy;
        }
        else {
            returnedEnergy = downWarp(aEnergyAmout, _orderedWarp);
        }
        toInfo();
        return returnedEnergy;

    }

    private int downWarp(int aEnergyAmout, double aInternalOrderedSpeed) {
        double tryWarp = MathUtil.round(aInternalOrderedSpeed - .2, 2);
        if (tryWarp < 0) {
            tryWarp = 0;
        }
        while (aEnergyAmout < calcolateEnergyNeed(tryWarp)) {
            tryWarp += -.2;
        }
        _effectiveWarp = MathUtil.round(tryWarp, 2);
        return aEnergyAmout - calcolateEnergyNeed(tryWarp);
    }

    private int calcolateEnergyNeed(double aSpeedWarp) {
        return MathUtil.integerPart(aSpeedWarp) * 5 + MathUtil.integerPart((MathUtil.decimalPart(aSpeedWarp) / .2)) * 2;
    }

    protected void toInfo() {
        _nacelleInfo.status(ITurnableComponent.ONLINE);
        _nacelleInfo.orderedwarp(_orderedWarp);
        _nacelleInfo.effectivewarp(_effectiveWarp);
    }

}
